package com.weyoung.app.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weyoung.app.mapper.GraveVisitingNodeMapper;
import com.weyoung.app.mapper.RelationMapper;
import com.weyoung.app.mapper.UserDetailMapper;
import com.weyoung.app.mapper.UserMapper;
import com.weyoung.app.service.RelationService;
import com.weyoung.common.consatant.exception.ClientException;
import com.weyoung.common.consatant.exception.ServiceException;
import com.weyoung.common.enums.UserErrorCodeEnum;
import com.weyoung.common.model.dto.app.GenerationQueryDTO;
import com.weyoung.common.model.dto.app.RelationNodeDTO;
import com.weyoung.common.model.dto.app.UpdateRelationNodeDTO;
import com.weyoung.common.model.dto.app.UpdateRelationNodeDetailDTO;
import com.weyoung.common.model.entity.FamilyRelation;
import com.weyoung.common.model.entity.UserDO;
import com.weyoung.common.model.entity.UserDetailDO;
import com.weyoung.common.model.vo.app.*;
import com.weyoung.common.utils.AES;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.HashMap;
import java.text.SimpleDateFormat;
import java.util.Objects;

import static com.weyoung.common.consatant.errorcode.BaseErrorCode.SERVICE_ERROR;

@Service
@RequiredArgsConstructor
@Slf4j
public class RelationServiceImpl extends ServiceImpl<RelationMapper, FamilyRelation> implements RelationService  {

    private final RelationMapper relationMapper;

    private final UserDetailServiceImpl userDetailService;

    private final UserServiceImpl userService;

    private final UserMapper userMapper;

    private final GraveVisitingNodeMapper  graveVisitingNodeMapper;

    private final UserDetailMapper userDetailMapper;


    /**
     * 获取家族中未建立族谱关系的成员
     * @param familyId 家族ID
     * @return 未建立族谱关系的成员列表
     */
    public List<UserDetailVO> getUnrelatedFamilyMembers(String familyId) {
        // 1. 获取家族中所有用户
        List<UserDetailVO> familyMembers = userMapper.getAllFamilyMembers(familyId);

        if (familyMembers.isEmpty()) {
            return new ArrayList<>();
        }

        // 2. 获取已建立族谱关系的用户ID列表
        List<Integer> relatedUserIds = this.lambdaQuery()
                .eq(FamilyRelation::getFamilyId, familyId)
                .select(FamilyRelation::getUserId)
                .list()
                .stream()
                .map(FamilyRelation::getUserId)
                .collect(Collectors.toList());

        // 3. 获取所有配偶ID列表
        List<Integer> spouseIds = new ArrayList<>();
        List<FamilyRelation> relations = this.lambdaQuery()
                .eq(FamilyRelation::getFamilyId, familyId)
                .select(FamilyRelation::getSpouseId)
                .list();
        
        if (relations != null) {
            for (FamilyRelation relation : relations) {
                if (relation != null && relation.getSpouseId() != null) {
                    spouseIds.add(relation.getSpouseId());
                }
            }
        }

        // 4. 过滤出未建立族谱关系且不是配偶的用户，并解密手机号和邮箱
        return familyMembers.stream()
                .filter(user -> !relatedUserIds.contains(user.getUserId()) && !spouseIds.contains(user.getUserId()))
                .peek(user -> {
                    if (user.getPhone() != null) {
                        user.setPhone(AES.decrypt(user.getPhone()));
                    }
                    if (user.getEmail() != null) {
                        user.setEmail(AES.decrypt(user.getEmail()));
                    }
                })
                .collect(Collectors.toList());
    }


    /**
     * 获取当前用户父系族谱树
     * @return 族谱树列表
     */
    public List<RelationTreeVO> getRelationTree() {
        // 获取当前用户ID
        Integer currentUserId = getCurrentUserId();
        if (currentUserId == null) {
            throw new ClientException("用户未登录");
        }
        // 获取当前用户家族
        String familyId = userMapper.getFamilyIdByUserId(currentUserId);

        // 1. 参数校验
        if (!StringUtils.hasText(familyId)) {
            throw new ClientException("家族ID不能为空");
        }

        // 2. 获取当前用户信息
        UserDO currentUser = userService.getById(currentUserId);
        if (currentUser == null) {
            throw new ClientException("用户不存在");
        }

        // 3. 查询出所有关系数据
        List<FamilyRelation> relationList = this.lambdaQuery()
                .eq(FamilyRelation::getFamilyId, familyId)
                .list();

        // 4. 将家族关系列表转换为RelationTreeVO列表
        List<RelationTreeVO> relationTreeVOList = relationList.stream()
                .map(relation -> {
                    RelationTreeVO relationTreeVO = new RelationTreeVO();
                    BeanUtil.copyProperties(relation, relationTreeVO);
                    // 查询用户信息
                    relationTreeVO.setUser(BeanUtil.copyProperties(userMapper.getUserDetailById(relation.getUserId()), UserTreeVO.class));
                    // 查询配偶信息
                    if (relation.getSpouseId() != null) {
                        relationTreeVO.setSpouse(BeanUtil.copyProperties(userMapper.getUserDetailById(relation.getSpouseId()), UserTreeVO.class));
                    }
                    return relationTreeVO;
                })
                .toList();

        // 5. 构建树形结构
        Map<Long, RelationTreeVO> relationMap = relationTreeVOList.stream()
                .collect(Collectors.toMap(RelationTreeVO::getRelationId, relation -> relation));

        List<RelationTreeVO> tree = new ArrayList<>();
        relationTreeVOList.forEach(relation -> {
            if (relation.getParentRelationId() == null || relation.getParentRelationId() == 0) {
                tree.add(relation);
            } else {
                RelationTreeVO parent = relationMap.get(relation.getParentRelationId());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(relation);
                }
            }
        });

        // 6. 对树形结构进行排序
        tree.sort(Comparator.comparing(child -> child.getUser().getBirthDate()));
        tree.forEach(this::sortChildren);

        // 7. 计算称谓
        if (currentUserId != null) {
            FamilyRelation currentUserRelation = relationList.stream()
                    .filter(relation -> relation.getUserId().equals(currentUserId))
                    .findFirst()
                    .orElse(null);

            if (currentUserRelation != null) {
                tree.forEach(node -> calculateTitle(node, currentUserRelation));
            }
        }

        return tree;
    }

    /**
     * 获取母系族谱树
     * @return 母系族谱树列表
     */
    @Override
    public List<RelationTreeVO> getMaternalRelationTree() {
        // 1. 获取当前用户信息
        Integer currentUserId = getCurrentUserId();
        if (currentUserId == null) {
            throw new ClientException("用户未登录");
        }

        // 2. 获取当前用户详细信息
        UserDetailDO currentUserDetail = userDetailService.getById(currentUserId);
        if (currentUserDetail == null || !StringUtils.hasText(currentUserDetail.getMotherUserId())) {
            throw new ClientException("未找到母亲信息");
        }

        // 3. 获取母亲信息
        UserDO mother = userService.getById(currentUserDetail.getMotherUserId());
        if (mother == null || !StringUtils.hasText(mother.getFamilyId())) {
            throw new ClientException("母亲信息不完整");
        }

        // 4. 查询母亲家族的所有关系数据
        List<FamilyRelation> relationList = this.lambdaQuery()
                .eq(FamilyRelation::getFamilyId, mother.getFamilyId())
                .list();
        if (relationList.isEmpty()) {
            throw new ClientException("未找到母亲家族关系数据");
        }

        // 5. 找到母亲节点
        FamilyRelation motherRelation = relationList.stream()
                .filter(relation -> relation.getUserId().equals(Integer.parseInt(currentUserDetail.getMotherUserId())))
                .findFirst()
                .orElseThrow(() -> new ClientException("未找到母亲在家族中的关系节点"));

        // 6. 构建树形结构
        Map<Long, RelationTreeVO> relationMap = new HashMap<>();
        List<RelationTreeVO> tree = new ArrayList<>();

        // 6.1 转换所有节点为VO对象
        relationList.forEach(relation -> {
            RelationTreeVO vo = new RelationTreeVO();
            BeanUtil.copyProperties(relation, vo);
            vo.setUser(BeanUtil.copyProperties(userMapper.getUserDetailById(relation.getUserId()), UserTreeVO.class));
            if (relation.getSpouseId() != null) {
                vo.setSpouse(BeanUtil.copyProperties(userMapper.getUserDetailById(relation.getSpouseId()), UserTreeVO.class));
            }
            relationMap.put(relation.getRelationId(), vo);
        });

        // 6.2 构建树形结构
        relationMap.values().forEach(vo -> {
            if (vo.getParentRelationId() == null || vo.getParentRelationId() == 0) {
                tree.add(vo);
            } else {
                RelationTreeVO parent = relationMap.get(vo.getParentRelationId());
                if (parent != null) {
                    if (parent.getChildren() == null) {
                        parent.setChildren(new ArrayList<>());
                    }
                    parent.getChildren().add(vo);
                }
            }
        });

        // 7. 添加当前用户节点到母亲节点下
        RelationTreeVO motherNode = relationMap.get(motherRelation.getRelationId());
        if (motherNode != null) {
            RelationTreeVO currentUserNode = new RelationTreeVO();
            currentUserNode.setRelationId(null);  // 设置为null，表示这是手动添加的节点
            currentUserNode.setFamilyId(mother.getFamilyId());
            UserTreeVO userDetailVO = BeanUtil.copyProperties(currentUserDetail, UserTreeVO.class);
            userDetailVO.setCurrentTitle("我");
            currentUserNode.setUser(userDetailVO);
            currentUserNode.setGeneration(motherRelation.getGeneration() + 1);
            currentUserNode.setParentRelationId(motherRelation.getRelationId());

            if (motherNode.getChildren() == null) {
                motherNode.setChildren(new ArrayList<>());
            }
            motherNode.getChildren().add(currentUserNode);
        }

        // 8. 排序和计算称谓
        tree.sort(Comparator.comparing(child -> child.getUser().getBirthDate()));
        tree.forEach(this::sortChildren);
        calculateMaternalTitles(tree, motherRelation.getRelationId(), currentUserId);

        return tree;
    }

    /**
     * 计算母系称谓
     * @param nodes 节点列表
     * @param motherRelationId 母亲的关系ID
     * @param currentUserId 当前用户ID
     */
    private void calculateMaternalTitles(List<RelationTreeVO> nodes, Long motherRelationId, Integer currentUserId) {
        // 获取当前用户的出生日期
        UserDetailDO currentUser = userDetailService.getById(currentUserId);
        Date currentUserBirthDate = currentUser != null ? currentUser.getBirthDate() : null;

        for (RelationTreeVO node : nodes) {
            // 如果是当前用户，跳过
            if (node.getUser().getUserId() != null && node.getUser().getUserId().equals(currentUserId)) {
                node.getUser().setCurrentTitle("我");
                continue;
            }

            // 如果是母亲节点
            if (node.getRelationId() != null && node.getRelationId().equals(motherRelationId)) {
                node.getUser().setCurrentTitle("母亲");
                if (node.getSpouse() != null) {
                    node.getSpouse().setCurrentTitle("父亲");
                }
            } 
            // 如果是母亲的父母（外祖父母）
            else if (node.getChildren() != null && node.getChildren().stream()
                    .anyMatch(child -> child.getRelationId() != null && child.getRelationId().equals(motherRelationId))) {
                boolean isMale = "male".equals(node.getUser().getGender());
                node.getUser().setCurrentTitle(isMale ? "外公" : "外婆");
                if (node.getSpouse() != null) {
                    node.getSpouse().setCurrentTitle(isMale ? "外婆" : "外公");
                }
            }
            // 如果是母亲的兄弟姐妹
            else if (node.getParentRelationId() != null && 
                    node.getParentRelationId().equals(getParentRelationId(motherRelationId)) &&
                    !node.getRelationId().equals(motherRelationId)) {
                boolean isMale = "male".equals(node.getUser().getGender());
                node.getUser().setCurrentTitle(isMale ? "舅舅" : "姨妈");
                if (node.getSpouse() != null) {
                    node.getSpouse().setCurrentTitle(isMale ? "舅妈" : "姨父");
                }
            }
            // 如果是母亲的兄弟姐妹的子女（表兄弟姐妹）
            else if (isCousinNode(node, motherRelationId)) {
                if (currentUserBirthDate != null && node.getUser() != null && node.getUser().getBirthDate() != null) {
                    boolean isMale = "male".equals(node.getUser().getGender());
                    boolean isOlder = node.getUser().getBirthDate().before(currentUserBirthDate);
                    
                    if (isMale) {
                        node.getUser().setCurrentTitle(isOlder ? "表哥" : "表弟");
                    } else {
                        node.getUser().setCurrentTitle(isOlder ? "表姐" : "表妹");
                    }
                    
                    // 设置配偶称谓
                    if (node.getSpouse() != null) {
                        if (isMale) {
                            node.getSpouse().setCurrentTitle(isOlder ? "表嫂" : "表弟媳");
                        } else {
                            node.getSpouse().setCurrentTitle(isOlder ? "表姐夫" : "表妹夫");
                        }
                    }
                }
            }

            // 递归处理子节点
            if (node.getChildren() != null) {
                calculateMaternalTitles(node.getChildren(), motherRelationId, currentUserId);
            }
        }
    }

    /**
     * 判断是否是表兄弟姐妹节点（母亲的兄弟姐妹的子女）
     */
    private boolean isCousinNode(RelationTreeVO node, Long motherRelationId) {
        if (node.getParentRelationId() == null) {
            return false;
        }

        // 获取父节点
        FamilyRelation parentRelation = this.getById(node.getParentRelationId());
        if (parentRelation == null) {
            return false;
        }

        // 判断父节点是否是母亲的兄弟姐妹（与母亲有相同的父节点）
        Long motherParentId = getParentRelationId(motherRelationId);
        return motherParentId != null && motherParentId.equals(parentRelation.getParentRelationId()) &&
               !motherRelationId.equals(parentRelation.getRelationId());
    }

    /**
     * 获取父节点的relationId
     */
    private Long getParentRelationId(Long relationId) {
        FamilyRelation relation = this.getById(relationId);
        return relation != null ? relation.getParentRelationId() : null;
    }

    /**
     * 递归排序子关系
     * @param relationTreeVO 关系树节点
     */
    private void sortChildren(RelationTreeVO relationTreeVO) {
        if (relationTreeVO.getChildren() != null && !relationTreeVO.getChildren().isEmpty()) {
            // 对当前节点的子节点进行排序
            relationTreeVO.setChildren(relationTreeVO.getChildren().stream()
                    .sorted(Comparator.comparing(child -> child.getUser().getBirthDate()))
                    .collect(Collectors.toList()));
            // 递归对每个子节点的子节点进行排序
            relationTreeVO.getChildren().forEach(this::sortChildren);
        }
    }

    /**
     * 递归计算称谓
     * @param node 当前节点
     * @param currentUserRelation 当前用户的关系信息
     */
    private void calculateTitle(RelationTreeVO node, FamilyRelation currentUserRelation) {
        // 计算当前节点的称谓
        String title = calculateTitleForNode(node, currentUserRelation);
        node.getUser().setCurrentTitle(title);

        // 计算配偶的称谓
        if (node.getSpouse() != null) {
            String spouseTitle = calculateSpouseTitle(title, node.getSpouse().getGender());
            node.getSpouse().setCurrentTitle(spouseTitle);
        }

        // 递归计算子节点的称谓
        if (node.getChildren() != null) {
            node.getChildren().forEach(child -> calculateTitle(child, currentUserRelation));
        }
    }

    /**
     * 计算单个节点的称谓
     */
    private String calculateTitleForNode(RelationTreeVO node, FamilyRelation currentUserRelation) {
        // 如果是当前用户自己
        if (node.getUser().getUserId().equals(currentUserRelation.getUserId())) {
            return "我";
        }

        // 如果是配偶
        if (node.getSpouse() != null && node.getSpouse().getUserId() != null && 
            node.getSpouse().getUserId().equals(currentUserRelation.getUserId())) {
            return "male".equals(node.getUser().getGender()) ? "丈夫" : "妻子";
        }

        // 获取性别
        boolean isMale = "male".equals(node.getUser().getGender());

        // 判断直系关系
        // 1. 判断是否是父母（当前节点的relationId等于当前用户的parentRelationId）
        if (currentUserRelation.getParentRelationId() != null && 
            currentUserRelation.getParentRelationId().equals(node.getRelationId())) {
            return isMale ? "父亲" : "母亲";
        }

        // 2. 判断是否是子女（当前节点的parentRelationId等于当前用户的relationId）
        if (node.getParentRelationId() != null && 
            node.getParentRelationId().equals(currentUserRelation.getRelationId())) {
            return isMale ? "儿子" : "女儿";
        }

        // 3. 判断兄弟姐妹（同一个父节点）
        if (node.getParentRelationId() != null && currentUserRelation.getParentRelationId() != null && 
            node.getParentRelationId().equals(currentUserRelation.getParentRelationId())) {
            return isMale ? "哥哥" : "姐姐";
        }

        // 4. 判断其他关系（根据世代差）
        int generationDiff = node.getGeneration() - currentUserRelation.getGeneration();
        
        // 旁系亲属
        if (generationDiff == 0) {
            // 同辈堂兄弟姐妹
            return isMale ? "堂兄" : "堂姐";
        } else if (generationDiff == -1) {
            // 父辈旁系
            return isMale ? "叔叔" : "姑姑";
        } else if (generationDiff == 1) {
            // 子辈旁系
            return isMale ? "侄子" : "侄女";
        } else if (generationDiff < -1) {
            // 祖辈
            if (generationDiff == -2) {
                return isMale ? "祖父" : "祖母";
            } else if (generationDiff == -3) {
                return isMale ? "曾祖父" : "曾祖母";
            } else {
                return isMale ? "高祖父" : "高祖母";
            }
        } else {
            // 孙辈
            if (generationDiff == 2) {
                return isMale ? "孙子" : "孙女";
            } else if (generationDiff == 3) {
                return isMale ? "曾孙" : "曾孙女";
            } else {
                return isMale ? "玄孙" : "玄孙女";
            }
        }
    }

    /**
     * 计算配偶的称谓
     * @param nodeTitle 当前节点的称谓
     * @param spouseGender 配偶的性别
     * @return 配偶的称谓
     */
    private String calculateSpouseTitle(String nodeTitle, String spouseGender) {
        boolean isMale = "male".equals(spouseGender);
        
        switch (nodeTitle) {
            case "我":
                return isMale ? "丈夫" : "妻子";
            case "父亲":
                return "母亲";
            case "母亲":
                return "父亲";
            case "儿子":
                return "儿媳";
            case "女儿":
                return "女婿";
            case "弟弟":
                return "弟媳";
            case "妹妹":
                return "妹夫";
            case "堂弟":
                return "堂弟媳";
            case "堂妹":
                return "堂妹夫";
            case "叔叔":
                return "婶婶";
            case "姑姑":
                return "姑父";
            case "侄子":
                return "侄媳";
            case "侄女":
                return "侄女婿";
            case "祖父":
                return "祖母";
            case "祖母":
                return "祖父";
            case "孙子":
                return "孙媳";
            case "孙女":
                return "孙女婿";
            case "曾祖父":
                return "曾祖母";
            case "曾祖母":
                return "曾祖父";
            case "曾孙":
                return "曾孙媳";
            case "曾孙女":
                return "曾孙女婿";
            case "高祖父":
                return "高祖母";
            case "高祖母":
                return "高祖父";
            case "玄孙":
                return "玄孙媳";
            case "玄孙女":
                return "玄孙女婿";
            default:
                return isMale ? "丈夫" : "妻子";
        }
    }

    /**
     * 获取当前登录用户ID
     * @return 用户ID
     */
    private Integer getCurrentUserId() {
        try {
            // 从Sa-Token中获取当前登录用户ID
            return StpUtil.getLoginIdAsInt();
//            return 1003;
        } catch (Exception e) {
            log.error("获取当前用户ID失败", e);
            return null;
        }
    }

    /**
     * 创建族谱节点
     */
    public FamilyRelation createRelationNode(RelationNodeDTO dto) {
        // 1. 参数校验已在DTO中完成

        // 2. 检查用户是否已存在关系
        FamilyRelation existingRelation = this.lambdaQuery()
                .eq(FamilyRelation::getFamilyId, dto.getFamilyId())
                .eq(FamilyRelation::getUserId, dto.getUserId())
                .one();
        if (existingRelation != null) {
            throw new ClientException("该用户已存在族谱关系");
        }

        // 3. 检查用户是否在指定家族中
        UserDetailVO user = userMapper.getUserDetailById(dto.getUserId());
        if (user == null) {
            throw new ClientException("用户不存在");
        }
        if (!dto.getFamilyId().equals(user.getFamilyId())) {
            throw new ClientException("该用户不属于该家族，请先加入家族");
        }

        // 4. 如果指定了父节点，验证父节点存在
        int generation; // 世代数
        if (dto.getParentRelationId() != null && dto.getParentRelationId() != 0) {
            FamilyRelation parentRelation = this.getById(dto.getParentRelationId());
            if (parentRelation == null) {
                throw new ClientException("父节点不存在");
            }
            if (!dto.getFamilyId().equals(parentRelation.getFamilyId())) {
                throw new ClientException("父节点不属于该家族");
            }
            generation = parentRelation.getGeneration() + 1;
        } else {
            // 根节点，世代数为1
            dto.setParentRelationId(0L);
            generation = 1;
        }

        // 5. 创建新节点
        FamilyRelation newRelation = new FamilyRelation();
        newRelation.setFamilyId(dto.getFamilyId());
        newRelation.setUserId(dto.getUserId());
        if (StringUtils.hasText(user.getSpouseUserId())) {
            newRelation.setSpouseId(Integer.valueOf(user.getSpouseUserId()));
        }
        newRelation.setParentRelationId(dto.getParentRelationId());
        newRelation.setGeneration(generation);
        newRelation.setRemarks(dto.getRemarks());
        newRelation.setCreateDate(new Date());
        newRelation.setUpdateDate(new Date());

        this.save(newRelation);
        return newRelation;
    }

    /**
     * 更新族谱节点
     */
    public void updateRelationNode(UpdateRelationNodeDTO dto) {
        // 1. 获取现有节点
        FamilyRelation existingRelation = this.getById(dto.getRelationId());
        if (existingRelation == null) {
            throw new ClientException("关系节点不存在");
        }

        // 2. 如果修改了用户ID，检查新用户是否已存在关系
        if (dto.getUserId() != null && !dto.getUserId().equals(existingRelation.getUserId())) {
            // 检查新用户是否属于该家族
            UserDO newUser = userService.getById(dto.getUserId());
            if (newUser == null) {
                throw new ClientException("用户不存在");
            }
            if (!existingRelation.getFamilyId().equals(newUser.getFamilyId())) {
                throw new ClientException("该用户不属于该家族");
            }

            // 检查新用户是否已存在其他族谱关系
            FamilyRelation duplicateRelation = this.lambdaQuery()
                    .eq(FamilyRelation::getFamilyId, existingRelation.getFamilyId())
                    .eq(FamilyRelation::getUserId, dto.getUserId())
                    .ne(FamilyRelation::getRelationId, dto.getRelationId())
                    .one();
            if (duplicateRelation != null) {
                throw new ClientException("该用户已存在其他族谱关系");
            }
        }

        // 3. 如果修改了父节点或世代数，进行验证
        if (dto.getParentRelationId() != null || dto.getGeneration() != null) {
            // 获取新的父节点
            FamilyRelation newParent = dto.getParentRelationId() != null ? this.getById(dto.getParentRelationId()) : null;
            
            // 验证父节点
            if (newParent != null) {
                if (!existingRelation.getFamilyId().equals(newParent.getFamilyId())) {
                    throw new ClientException("父节点不属于该家族");
                }
                if (dto.getGeneration() != null && dto.getGeneration() != newParent.getGeneration() + 1) {
                    throw new ClientException("世代数必须比父节点大1");
                }
            } else if (dto.getGeneration() != null && dto.getGeneration() != 1) {
                throw new ClientException("无父节点的世代数必须为1");
            }

            // 检查是否形成循环
            if (newParent != null) {
                if (isAncestor(dto.getRelationId(), dto.getParentRelationId())) {
                    throw new ClientException("不能将节点设置为其子孙节点的子节点");
                }
            }
        }

        // 4. 更新节点
        FamilyRelation updateRelation = new FamilyRelation();
        updateRelation.setRelationId(dto.getRelationId());
        if (dto.getUserId() != null) {
            updateRelation.setUserId(dto.getUserId());
        }
        if (dto.getParentRelationId() != null) {
            updateRelation.setParentRelationId(dto.getParentRelationId());
        }
        if (dto.getGeneration() != null) {
            updateRelation.setGeneration(dto.getGeneration());
        }
        if (dto.getRemarks() != null) {
            updateRelation.setRemarks(dto.getRemarks());
        }
        updateRelation.setUpdateDate(new Date());

        this.updateById(updateRelation);
    }

    /**
     * 递归删除族谱节点及其所有子节点
     * @param relationId 关系ID
     */
    @Override
    @Transactional
    public void deleteRelationNodeRecursive(Long relationId) {
        List<Long> allIds = new ArrayList<>();
        collectAllRelationIds(relationId, allIds);
        if (allIds.isEmpty()) {
            throw new ClientException("未找到要删除的节点");
        }
        this.removeByIds(allIds);
    }

    /**
     * 递归收集所有子节点ID
     */
    private void collectAllRelationIds(Long relationId, List<Long> idList) {
        idList.add(relationId);
        List<FamilyRelation> children = this.lambdaQuery()
            .eq(FamilyRelation::getParentRelationId, relationId)
            .list();
        for (FamilyRelation child : children) {
            collectAllRelationIds(child.getRelationId(), idList);
        }
    }

    /**
     * 检查节点A是否是节点B的祖先
     * @param relationIdA 节点A的ID
     * @param relationIdB 节点B的ID
     * @return 是否是祖先
     */
    private boolean isAncestor(Long relationIdA, Long relationIdB) {
        if (relationIdA == null || relationIdB == null) {
            return false;
        }
        if (relationIdA.equals(relationIdB)) {
            return true;
        }
        
        FamilyRelation relationB = this.getById(relationIdB);
        if (relationB == null || relationB.getParentRelationId() == null) {
            return false;
        }
        
        return isAncestor(relationIdA, relationB.getParentRelationId());
    }

    /**
     * 设置配偶关系
     * @param relationId 关系ID
     * @param spouseId 配偶用户ID
     */
    @Transactional
    public void setSpouse(Long relationId, Integer spouseId) {
        // 1. 获取关系节点
        FamilyRelation relation = this.getById(relationId);
        if (relation == null) {
            throw new ClientException("关系节点不存在");
        }

        // 2. 检查配偶是否存在
        UserDO spouse = userService.getById(spouseId);
        if (spouse == null) {
            throw new ClientException("配偶用户不存在");
        }

        // 3. 检查配偶是否已经是其他节点的配偶
        FamilyRelation existingSpouse = this.lambdaQuery()
                .eq(FamilyRelation::getSpouseId, spouseId)
                .ne(FamilyRelation::getRelationId, relationId)
                .one();
        if (existingSpouse != null) {
            throw new ClientException("该用户已经是其他节点的配偶");
        }

        // 4. 更新族谱节点配偶关系
        FamilyRelation updateRelation = new FamilyRelation();
        updateRelation.setRelationId(relationId);
        updateRelation.setSpouseId(spouseId);
        updateRelation.setUpdateDate(new Date());
        this.updateById(updateRelation);

        // 5. 更新用户详细信息表
        userDetailService.lambdaUpdate()
                .set(UserDetailDO::getSpouseUserId, spouseId)
                .eq(UserDetailDO::getUserId, relation.getUserId())
                .update();
    }

    /**
     * 删除配偶关系
     * @param relationId 关系ID
     * @return 更新后的族谱节点
     */
    public void removeSpouse(Long relationId) {
        // 1. 获取关系节点
        FamilyRelation relation = this.getById(relationId);
        if (relation == null) {
            throw new ClientException("关系节点不存在");
        }

        // 2. 检查是否存在配偶
        if (relation.getSpouseId() == null) {
            throw new ClientException("该节点没有配偶关系");
        }

        // 3. 更新配偶关系
        FamilyRelation updateRelation = new FamilyRelation();
        updateRelation.setRelationId(relationId);
        updateRelation.setSpouseId(null);
        updateRelation.setUpdateDate(new Date());

        this.updateById(updateRelation);

        // 4. 更新用户详细信息表
        userDetailService.lambdaUpdate()
                .set(UserDetailDO::getSpouseUserId, null)
                .eq(UserDetailDO::getUserId, relation.getUserId())
                .update();

    }

    /**
     * 获取指定世代的所有节点
     * @param dto 世代查询参数
     * @return 指定世代的族谱节点列表
     */
    public List<FamilyRelation> getNodesByGeneration(GenerationQueryDTO dto) {
        return this.lambdaQuery()
                .eq(FamilyRelation::getFamilyId, dto.getFamilyId())
                .eq(FamilyRelation::getGeneration, dto.getGeneration())
                .list();
    }

    /**
     * 获取指定节点的详细信息
     * @param userId 用户ID
     * @return 节点详细信息
     */
    public RelationNodeDetailVO getRelationNodeDetail(Integer userId) {
        // 1. 获取用户详细信息
        UserDetailVO userDetail = userMapper.getUserDetailById(userId);
        if (userDetail == null) {
            throw new ClientException("未找到用户信息");
        }

        // 3. 获取族谱关系信息
        FamilyRelation relation = this.lambdaQuery()
                .eq(FamilyRelation::getUserId, userId)
                .eq(FamilyRelation::getFamilyId, userDetail.getFamilyId())
                .one();
        if (relation == null) {
            throw new ClientException("未找到族谱关系信息");
        }

        // 4. 构建返回对象
        RelationNodeDetailVO vo = new RelationNodeDetailVO();
        
        // 4.1 设置基本信息
        vo.setUserId(userId);
        vo.setFamilyId(userDetail.getFamilyId());
        vo.setRole(userDetail.getRole());
        vo.setUserPic(userDetail.getUserPic());
        
        // 4.2 设置详细信息
        vo.setRealName(userDetail.getRealName());
        vo.setGender(userDetail.getGender());
        vo.setAge(userDetail.getAge());
        vo.setPhone(AES.decrypt(userDetail.getPhone()));
        vo.setEmail(AES.decrypt(userDetail.getEmail()));
        vo.setAddressInfo(userDetail.getAddressInfo());
        vo.setBirthDate(userDetail.getBirthDate());
        vo.setIsAlive(userDetail.getIsAlive());
        vo.setDeathDate(userDetail.getDeathDate());
        String graveAddress = graveVisitingNodeMapper.getGraveAddress(userDetail.getFamilyId(), userDetail.getRealName());
        vo.setGraveAddress(graveAddress != null ? graveAddress : "");
        vo.setUserIntro(userDetail.getUserIntro());
        vo.setLifeImage(userDetail.getLifeImage());
        vo.setLifeAudio(userDetail.getLifeAudio());
        vo.setLifeVideo(userDetail.getLifeVideo());

        // 4.3 设置直系亲属关系
        Map<String, String> directRelative = new HashMap<>();

        // 获取配偶信息
        if (relation.getSpouseId() != null) {
            UserDetailVO spouseDetail = userMapper.getUserDetailById(relation.getSpouseId());
            if (spouseDetail != null) {
                // 根据性别设置配偶称谓
                String spouseKey = "male".equals(spouseDetail.getGender()) ? "丈夫" : "妻子";
                directRelative.put(spouseKey, spouseDetail.getRealName());
                // 获取子女信息
                List<FamilyRelation> children;
                if ("丈夫".equals(spouseKey)){
                    // 如果是母亲，需要找到丈夫的关系节点
                    FamilyRelation husbandRelation = this.lambdaQuery()
                            .eq(FamilyRelation::getUserId, spouseDetail.getUserId())
                            .eq(FamilyRelation::getFamilyId, spouseDetail.getFamilyId())
                            .one();
                    if (husbandRelation != null) {
                        // 通过丈夫的关系节点查询子女
                        children = this.lambdaQuery()
                                .eq(FamilyRelation::getParentRelationId, husbandRelation.getRelationId())
                                .list();
                    } else {
                        children = new ArrayList<>();
                    }
                }else {
                    // 如果是父亲，直接查询子女
                    children = this.lambdaQuery()
                            .eq(FamilyRelation::getParentRelationId, relation.getRelationId())
                            .list();
                }
                if (!children.isEmpty()) {
                    List<String> childrenNames = new ArrayList<>();
                    for (FamilyRelation child : children) {
                        UserDetailVO childDetail = userMapper.getUserDetailById(child.getUserId());
                        if (childDetail != null) {
                            childrenNames.add(childDetail.getRealName());
                        }
                    }
                    directRelative.put("子女", String.join("、", childrenNames));
                }
            }
        }

        // 获取父母信息
        if (relation.getParentRelationId() != null) {
            FamilyRelation parentRelation = this.getById(relation.getParentRelationId());
            if (parentRelation != null) {
                UserDetailVO parentDetail = userMapper.getUserDetailById(parentRelation.getUserId());
                if (parentDetail != null) {
                    directRelative.put("父亲", parentDetail.getRealName());
                }
                if (parentRelation.getSpouseId() != null) {
                    UserDetailVO motherDetail = userMapper.getUserDetailById(parentRelation.getSpouseId());
                    if (motherDetail != null) {
                        directRelative.put("母亲", motherDetail.getRealName());
                    }
                }
            }
        }

        vo.setDirectRelative(directRelative);

        return vo;
    }

    /**
     * 更新族谱节点详细信息
     * @param dto 族谱节点详细信息更新参数
     */
    @Override
    @Transactional
    public void updateRelationNodeDetail(UpdateRelationNodeDetailDTO dto) {
        // 1. 获取用户详细信息
        UserDetailDO userDetail = userDetailService.getById(dto.getUserId());
        if (userDetail == null) {
            throw new ClientException("未找到用户信息");
        }

        // 2. 加密敏感信息
        if (dto.getPhone() != null) {
            dto.setPhone(AES.encrypt(dto.getPhone()));
        }
        if (dto.getEmail() != null) {
            dto.setEmail(AES.encrypt(dto.getEmail()));
        }

        // 3. 更新用户和用户详细信息
        int rows = relationMapper.updateRelationNodeDetail(dto);
        if (rows == 0) {
            throw new ClientException("更新失败，请检查数据是否正确");
        }

        // 4. 如果提供了墓地地址，更新墓地地址
        if (dto.getGraveAddress() != null && dto.getRealName() != null) {
            int graveRows = relationMapper.updateGraveAddress(dto.getUserId(), dto.getRealName(), dto.getGraveAddress());
            if (graveRows == 0) {
                log.warn("更新墓地地址失败，用户ID: {}, 姓名: {}", dto.getUserId(), dto.getRealName());
            }
        }
    }

}